<!--
 * @Author: DaTree
 * @Date: 2021-07-15 15:12:24
 * @LastEditTime: 2021-11-10 19:09:08
 * @LastEditors: DaTree
 * @Description: DaTreeEdit
 * @FilePath: \www\src\components\VideoPlayerPlatform\index.vue
 * 天将降大任于是人也，必先苦其心志，劳其筋骨，饿其体肤，空乏其身，行拂乱其所为。 ——《孟子•告子下》
 * Copyright 2021 DaTree
-->
<template>
  <div class="video-box-warp">
    <!-- <LivePlayer  :id="'video_player_'+index" class="video-player" fluent autoplay live stretch></LivePlayer> -->
    <!-- <live-player video-url="ws://10.10.18.13/live/r44.flv?vhost=__defaultVhost__" alt="" :class="{'video-player':true}" :id="'video_player_'+index" live="true" stretch="true" /> -->
    <div class="video-box" @mouseup="handleBoxMouseUp">
      <div class="video-item" v-for="(item,index) of state.layouts" :class="['_'+layouts[state.currentLayout],(state.activeIndex===index?'active':'')]" :key="'item_'+index" @click="handleClickVideoItem(index)">
        <div :class="{'video-player':true}" :id="'video_player_'+index" @dblclick="handleDbClickVideoItem(index)" />
        <div class="tool-bar-base" v-if="item!==null&&item!==undefined">
          <div class="tool-btn" @click="handleCloseChannel(index)">
            <svg class="icon" aria-hidden="true">
              <title>关闭</title>
              <use xlink:href="#icon-close1"></use>
            </svg>
          </div>
        </div>
        <div class="player-loading" v-if="item!==null&&item!==undefined" :class="{show:item.isLoading}">
          <img src="/font/player/loading.svg" width="50" alt="">
        </div>

        <div class="tool-bar-ptz" v-if="item!==null&&item!==undefined&&item.isOpenPtz">
          <div class="tool-bar-ptz-btn" @mousedown="handleStartPtzLeft">
            <svg class="icon" aria-hidden="true">
              <title>左</title>
              <use xlink:href="#icon-ptz-left"></use>
            </svg>
          </div>
          <div class="tool-bar-ptz-btn right" @mousedown="handleStartPtzRight">
            <svg class="icon" aria-hidden="true">
              <title>右</title>
              <use xlink:href="#icon-ptz-right"></use>
            </svg>
          </div>
          <div class="tool-bar-ptz-btn top" @mousedown="handleStartPtzUp">
            <svg class="icon" aria-hidden="true">
              <title>上</title>
              <use xlink:href="#icon-ptz-up"></use>
            </svg>
          </div>
          <div class="tool-bar-ptz-btn bottom" @mousedown="handleStartPtzDown">
            <svg class="icon" aria-hidden="true">
              <title>下</title>
              <use xlink:href="#icon-ptz-down"></use>
            </svg>
          </div>
        </div>
        <div class="tool-bar-base bottom" title="变倍+" v-if="item!==null&&item!==undefined">
          <div class="tool-btn" @mousedown="handleStartZoomUp($event,item)">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-bianbei"></use>
            </svg>
          </div>
          <div class="tool-btn" title="变倍-" @mousedown="handleStartZoomDown($event,item)">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-bianbei-"></use>
            </svg>
          </div>
          <div class="tool-btn" title="光圈+" @mousedown="handleStartFocusUp($event,item)">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-guangquan"></use>
            </svg>
          </div>
          <div class="tool-btn" title="光圈-" @mousedown="handleStartFocusDown($event,item)"> <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-guangquan-"></use>
            </svg>
          </div>
          <div class="tool-btn" :title="item.isOpenIntercom?'正在对讲':'对讲'" :class="{active:item.isOpenIntercom}" @click="handleIntercom(index)">
            <svg class="icon" aria-hidden="true" v-if="item.isOpenIntercom">
              <use xlink:href="#icon-mic"></use>
            </svg>
            <svg class="icon" aria-hidden="true" v-else>
              <use xlink:href="#icon-mic-off"></use>
            </svg>
          </div>
          <div class="tool-btn" :title="item.isOpenAudio?'正在播放声音':'声音'" :class="{active:item.isOpenAudio}" @click="handleMuted(index)">
            <svg class="icon" aria-hidden="true" v-if="item.isOpenAudio">
              <use xlink:href="#icon-volume-up"></use>
            </svg>
            <svg class="icon" aria-hidden="true" v-else>
              <use xlink:href="#icon-volume-off"></use>
            </svg>
          </div>

          <div class="tool-btn" :title="item.isOpenRecord?'正在录像':'录像'" :class="{active:item.isOpenRecord}" @click="handleRecord(index)">
            <svg class="icon" v-if="item.isOpenRecord" aria-hidden="true">
              <use xlink:href="#icon-shexiangji"></use>
            </svg>
            <svg class="icon" v-else aria-hidden="true">
              <use xlink:href="#icon-shexiangji"></use>
            </svg>

          </div>
          <div class="tool-btn" title="拍照" @click="handleSnap(index)">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-paizhao"></use>
            </svg>
          </div>
          <div class="tool-btn" :title="item.isOpenPtz?'正在云台控制':'云台'" @click="handlePtz(index)" :class="{active:item.isOpenPtz}">
            <svg class="icon" v-if="item.isOpenPtz" aria-hidden="true">
              <use xlink:href="#icon-yuntaikongzhi"></use>
            </svg>
            <svg class="icon" v-else aria-hidden="true">
              <use xlink:href="#icon-yuntaikongzhi"></use>
            </svg>
          </div>
          <div class="tool-btn" title="全屏" @click="handleFullscreen(index)">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-quanping1-mianxing"></use>
            </svg>
          </div>

        </div>
      </div>
    </div>
    <div class="tool-bar">
      <div class="tool-bar-item" @click="handleCloseAllChannel">
        <svg class="icon" aria-hidden="true">
          <title>全部关闭</title>
          <use xlink:href="#icon-close_all"></use>
        </svg>
      </div>
      <div class="tool-bar-item" @click="state.showLayouts=true">
        <svg class="icon" aria-hidden="true">
          <title>切换布局</title>
          <use xlink:href="#icon-buju1"></use>
        </svg>

        <div class="icon-layout" :class="{show:state.showLayouts}" @mouseleave="state.showLayouts=false">
          <div class="icon-layout-item" @click="handleSetLayout(item)" v-for="(item,index) in layoutArray" :class="{active: layoutStr===item}" :key="'icon_layout_item'+index">
            <span>{{item}}</span>
          </div>
        </div>
      </div>

    </div>
  </div>
</template>
<script>
import { defineComponent, reactive, watch, onMounted, ref, nextTick, computed } from "vue";
// import JessibucaPlayer from './players/jessibucaPlayer.js'
import ZlmRtcPlayer from './players/zlmRtcPlayer.js'
import linq from "linq";
// export interface ChinaMobileIndividualInterface {
//   /**
//    * 设置布局
//    */
//   setLayout(layout: string): void;
//   /**
//    * 打开视频通道
//    */
//   openVideoChannel(puid: string): any;
//   /**
//    * 打开对讲通道
//    */
//   openAudioChannel(puid: string): void;
//   /**
//    * 打开gps通道
//    */
//   openGpsChannel(puid: string, isOpen: boolean): void;
//   /**
//    * 获取gps轨迹 支持await
//    * @param puid
//    * @param beginTime 时间戳
//    * @param endTime 时间戳
//    */
//   getGpsRecordsV2(
//     puid: string,
//     beginTime?: number,
//     endTime?: number
//   ): Promise<any>;
//   getGpsRecordsV1(
//     puid: string,
//     beginTime?: number,
//     endTime?: number
//   ): Promise<any>;
//   /**
//    * 初始化组件
//    */
//   init(param: {
//     platformUrl: string;
//     addr: string;
//     port: number;
//     username: string;
//     pwd: string;
//   }): void;
// }

export default defineComponent({
  components: {
  },
  setup (props, ctx) {
    // return {};
    console.log(props);
    const layouts = {
      "1x1": 1,
      "1x2": 2,
      "2x2": 4,
      "2x3": 6,
      "3x3": 9,
      "3x4": 12,
      "4x4": 16,
      "4x6": 24,
      // "4x8": 32,
      1: "1x1",
      2: "1x2",
      4: "2x2",
      6: '2x3',
      9: "3x3",
      12: "3x4",
      16: "4x4",
      24: "4x6",
      // 32: "4x8",
    }
    const layoutArray = []
    for (const key in layouts) {
      if (new RegExp('\\d[x]\\d').test(key)) {
        layoutArray.push(key);
      }
    }

    const state = reactive({
      activeIndex: 0,
      layouts: new Array(),
      currentLayout: layouts["2x2"],
      showLayouts: false,
      doing: {},
    });
    const layoutStr = computed(() => {
      return layouts[state.currentLayout];
    })
    const players = state.layouts;

    watch(
      state,
      (newVal) => {
        newVal.layouts.length = newVal.currentLayout;
      },
      {
        immediate: true,
        deep: true,
      }
    );
    const methods = {
      /**
       * 设置布局
       */
      handleSetLayout (layout) {
        const layoutLength = layouts[layout];
        //切换布局就需要销毁一些播放器。
        for (let index = layoutLength; index < players.length; index++) {
          const element = players[index];
          if (element && element.player) {
            element.player.destroy()
          }
        }
        state.currentLayout = layoutLength;

        // nextTick(() => {
        //   for (const key in players) {
        //     if (Object.hasOwnProperty.call(players, key)) {
        //       const element = players[key];
        //       if (element.player) {
        //         element.player.resize()
        //       }
        //     }
        //   }
        // })
      },
      getPlayerEl (index) {
        return document.querySelector('#video_player_' + index);
      },
      handleCloseChannel (index) {
        const oldObj = players[index];
        //如果播放器已经初始化则销毁
        if (oldObj && oldObj.player) {
          try {
            oldObj.player.destroy();
          } catch (error) {
            console.log(error)
          }
        }
        players[index] = null;
      },
      handleCloseAllChannel () {
        for (let index = 0; index < players.length; index++) {
          const oldObj = players[index];
          //如果播放器已经初始化则销毁
          if (oldObj && oldObj.player) {
            try {
              oldObj.player.destroy();
            } catch (error) {
              console.log(error)
            }
          }
          players[index] = null;
        }
      },
      /**
       * 打开通道
       */
      openChannel ({ deviceName, deviceId, channelId }) {
        console.log(deviceName)
        console.log(deviceId)
        const me = this;
        return new Promise((resolve) => {
          // let videoUrl = `http://localhost/index/api/webrtc?app=live&stream=r44&type=play`
          // if (channelId === `c_0000002`) {
          //   videoUrl = `http://localhost/index/api/webrtc?app=live&stream=vl&type=play`
          // } else if (channelId === 'c_0000003') {
          //   videoUrl = `http://localhost/index/api/webrtc?app=live&stream=ir&type=play`
          // }


          let videoUrl = `/mediaserver/index/api/webrtc?app=live&stream=r44&type=play`
          if (channelId === `c_0000002`) {
            videoUrl = `/mediaserver/index/api/webrtc?app=live&stream=vl&type=play`
          } else if (channelId === 'c_0000003') {
            videoUrl = `/mediaserver/index/api/webrtc?app=live&stream=ir&type=play`
          }


          const oldObj = players[state.activeIndex];
          //如果播放器已经初始化则销毁
          if (oldObj && oldObj.player) {
            try {
              oldObj.player.destroy();
            } catch (error) {
              console.log(error)
            }
          }
          const playerObj = {
            container: me.getPlayerEl(state.activeIndex),
            player: null,
            //开启音频
            isOpenAudio: false,
            //开启对讲
            isOpenIntercom: false,
            //开启云台
            isOpenPtz: false,
            //开启录像
            isOpenRecord: false,
            //正在加载
            isLoading: false
          };
          const player = new ZlmRtcPlayer({
            container: playerObj.container,
            onplaying () {
              if (players[state.activeIndex]) {
                players[state.activeIndex].isLoading = false
                me.updateActiveIndex();
              }
            }
          })
          playerObj.player = player;
          players.splice(state.activeIndex, 1, playerObj)
          playerObj.isLoading = true
          nextTick(() => {
            player.init().then(() => {
              player.play(videoUrl);
              resolve()
            });
          })

        });
      },
      /**
       * 双击视频窗口
       */
      handleDbClickVideoItem (index) {
        this.handleFullscreen(index);
      },
      /**
       * 全屏
       */
      handleFullscreen (index) {
        const oldObj = players[index];
        if (oldObj && oldObj.player) {
          try {
            oldObj.player.setFullscreen();
          } catch (error) {
            console.log(error)
          }
        }
      },
      /**
       * 截图
       */
      handleSnap (index) {
        const oldObj = players[index];
        if (oldObj && oldObj.player) {
          try {
            oldObj.player.snap((blob) => {
              var link = document.createElement('a');
              link.download = new Date().toLocaleString().replace(/\//g, '').replace(/ /g, '').replace(/上午/g, '').replace(/下午/g, '').replace(/:/g, '') + '.png';
              link.href = URL.createObjectURL(blob);
              link.click();
              link = null;
            });
          } catch (error) {
            console.log(error)
          }
        }
      },
      /**
       * 设置/取消静音
       */
      handleMuted (index) {
        const oldObj = players[index];
        if (oldObj && oldObj.player) {
          try {
            oldObj.isOpenAudio = !oldObj.isOpenAudio;
            oldObj.player.setMuted(oldObj.isOpenAudio);
          } catch (error) {
            console.log(error)
          }
        }
      },
      /**
       * 打开或关闭对讲
       */
      async handleIntercom (index) {
        const oldObj = players[index];
        if (oldObj && oldObj.player) {
          try {
            oldObj.isOpenIntercom = !oldObj.isOpenIntercom;
          } catch (error) {
            console.log(error)
          }
        }
      },
      /**
       * 录像
       */
      async handleRecord (index) {
        const oldObj = players[index];
        if (oldObj && oldObj.player) {
          try {
            oldObj.isOpenRecord = !oldObj.isOpenRecord;
            // oldObj.player.setMuted(oldObj.isOpenIntercom);
          } catch (error) {
            console.log(error)
          }
        }
      },
      /**
       * 开启云台
       */
      async handlePtz (index) {
        const oldObj = players[index];
        if (oldObj && oldObj.player) {
          try {
            oldObj.isOpenPtz = !oldObj.isOpenPtz;
            // oldObj.player.setMuted(oldObj.isOpenIntercom);
          } catch (error) {
            console.log(error)
          }
        }
      },
      /**
       * 调焦变倍相关
       */
      handleStartZoomUp (e, item, action = 'zoomup') {
        e.target.classList.add('active')
        state.doing = {
          action,
          params: [e.target, item],
          func: function () {
            state.doing.params[0].classList.remove('active')
            // 调用 API 或者 抛出
            ctx.emit('actionstop', state.doing)
          }
        }
        ctx.emit('actionstart', state.doing)
      },
      handleStartZoomDown (e, item) {
        this.handleStartZoomUp(e, item, 'zoomdown')
      },
      handleStartFocusUp (e, item) {
        this.handleStartZoomUp(e, item, 'focusup')
      },
      handleStartFocusDown (e, item) {
        this.handleStartZoomUp(e, item, 'focusdown')
      },
      /**
       * 云台上下左右
       */
      handleStartPtzUp (e, item) {
        this.handleStartZoomUp(e, item, 'ptzup')
      },
      handleStartPtzDown (e, item) {
        this.handleStartZoomUp(e, item, 'ptzdown')
      },
      handleStartPtzLeft (e, item) {
        this.handleStartZoomUp(e, item, 'ptzleft')
      },
      handleStartPtzRight (e, item) {
        this.handleStartZoomUp(e, item, 'ptzright')
      },
      /**
       * 统一鼠标抬起处理
       */
      handleBoxMouseUp () {
        if (state.doing && state.doing.func) {
          state.doing.func();
          state.doing = {}
        }
        return true
      },
      /**
       * 更新当前容器索引
       */
      updateActiveIndex () {
        if (state.activeIndex < state.layouts.length - 1) {
          state.activeIndex++;
        } else {
          state.activeIndex = 0;
        }
      },
      /**
       * 点击播放器容器
       */
      handleClickVideoItem (index) {
        state.activeIndex = index;
      },
    };
    onMounted(() => {
      // nextTick(() => {
      // console.log(players)
      // debugger
      // })

      // document.querySelector('#video_player_0');
    })
    return {
      layoutStr,
      state,
      layouts,
      layoutArray,
      ...methods,
    };
  },
});
</script>
<style lang="scss" scoped>
.video-box-warp {
  position: relative;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  & * {
    box-sizing: border-box;
  }

  .video-box {
    flex: 1;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    border: 1px solid #000;
    box-sizing: border-box;
    background-color: #000;
    .video-item {
      border: 1px solid #000;
      flex: 0 0 50%;
      background-color: #262626;
      position: relative;
      &._1x1 {
        flex: 0 0 100%;
      }
      &._2x3 {
        flex: 0 0 33.33%;
      }
      &._3x3 {
        flex: 0 0 33.33%;
      }
      &._3x4 {
        flex: 0 0 25%;
      }
      &._4x4 {
        flex: 0 0 25%;
      }
      &._4x6 {
        flex: 0 0 16.66%;
      }
      &._4x8 {
        flex: 0 0 12.5%;
      }
      &.active {
        border-color: #ffcc00;
      }
      .player-loading {
        width: 100%;
        height: 100%;
        position: absolute;
        display: none;
        justify-content: center;
        align-content: center;
        align-items: center;
        justify-items: center;
        top: 0;
        left: 0;
        &.show {
          display: flex;
        }
      }
      .video-player {
        width: 100%;
        height: 100%;
        position: relative;
      }

      &:hover {
        .tool-bar-base {
          display: flex;
        }
      }

      .tool-bar-base {
        top: 0;
        width: 100%;
        height: 30px;
        display: none;
        justify-content: flex-end;
        justify-items: flex-end;
        align-content: center;
        align-items: center;
        position: absolute;
        flex-direction: row;
        background-color: rgba(0, 0, 0, 0.5);
        .tool-btn {
          display: flex;
          justify-content: flex-end;
          justify-items: flex-end;
          flex-direction: row;
          align-content: center;
          align-items: center;
          height: 100%;
          cursor: pointer;
          &.active {
            .icon {
              fill: #ffcc00;
            }
          }
        }

        .icon {
          fill: #ffffff;
          margin-right: 0.3rem;
          pointer-events: none;
        }
        &.bottom {
          top: unset;
          bottom: 0;
        }
      }

      .tool-bar-ptz {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        .tool-bar-ptz-btn {
          position: absolute;
          width: 50px;
          height: 50px;
          top: calc(50% - 25px);
          left: calc(50% - 75px);
          display: flex;
          opacity: 0.7;
          cursor: pointer;
          &:hover {
            opacity: 0.7;
          }
          &.active {
            opacity: 0.7;

            .icon {
              animation: changefillcolor_active 3s infinite linear;
            }
          }
          justify-content: center;
          justify-items: center;
          align-content: center;
          align-items: center;
          &.right {
            top: calc(50% - 25px);
            left: calc(50% + 25px);
          }
          &.top {
            top: calc(50% - 75px);
            left: calc(50% - 25px);
          }
          &.bottom {
            top: calc(50% + 25px);
            left: calc(50% - 25px);
          }

          .icon {
            width: 1.5rem;
            height: 1.5rem;
            fill: #000000;
            pointer-events: none;
            animation: changefillcolor 5s infinite linear;
          }
        }
      }
    }
  }
  .tool-bar {
    height: 40px;
    padding: 5px;
    display: flex;
    justify-content: flex-end;
    justify-items: flex-end;
    flex-direction: row;
    align-content: center;
    align-items: center;
    width: 100%;
    background-color: #3d3d3d;
    border: 2px solid #000;
    border-top: 0;
    border-bottom: 0;
    .tool-bar-item {
      display: flex;
      position: relative;
      height: 100%;
      justify-content: center;
      justify-items: center;
      align-content: center;
      align-items: center;
      cursor: pointer;

      .icon-layout {
        &.show {
          display: grid;
        }
        display: none;
        position: absolute;
        width: 200px;
        height: 200px;
        bottom: 35px;
        right: -5px;
        background-color: #3d3d3d;
        border: 2px solid #000;
        border-bottom: 0;

        grid-template-columns: repeat(3, 33.33%);
        grid-template-rows: repeat(3, 33.33%);
        grid-row-gap: 2px;
        grid-column-gap: 2px;
        .icon-layout-item {
          color: #fff;
          display: flex;
          justify-content: center;
          justify-items: center;
          align-content: center;
          align-items: center;
          cursor: pointer;
          &.active {
            color: #ffcc00;
          }
        }
      }
    }
    .icon {
      fill: #ffffff;
      margin-right: 0.3rem;
      pointer-events: none;
    }
  }
}
@keyframes changefillcolor {
  0% {
    fill: #000000;
  }
  25% {
    fill: #888888;
  }
  50% {
    fill: #ffffff;
  }
  75% {
    fill: #777777;
  }
  100% {
    fill: #000000;
  }
}
@keyframes changefillcolor_active {
  0% {
    fill: #ffcc00;
  }
  25% {
    fill: #ffdd57;
  }
  50% {
    fill: #FFFFFF;
  }
  75% {
    fill: #ffdd57;
  }
  100% {
    fill: #ffcc00;
  }
}
</style>
<style >
.video_player_zlm {
  width: 100%;
  height: 100%;
  position: absolute;
  object-fit: contain;
}
</style>